﻿using System;
using System.Collections.Generic;

using System.Windows;
using System.Windows.Controls;

using System.Windows.Input;
using System.Windows.Navigation;

using EagleJournal.Components;

using EagleJournalBE.Util;
using EagleJournalBE.Database.Tables;

namespace EagleJournal
{
    public struct POPanelEdit
    {
        public string   ID;
        public string   Description;
        public string   Amount;
        public long     Deadline;
        public string   Company;
    }

	public partial class PanelOrderEdit : UserControl
    {
        public static readonly  DependencyProperty
            CreateModeProperty          = DependencyProperty.Register("CreateMode", typeof(bool), typeof(PanelOrderEdit));
        public                  bool
            CreateMode
        {
            get { return (bool)this.GetValue(CreateModeProperty); }
            set { this.SetValue(CreateModeProperty, value); }
        }

        public static readonly  RoutedEvent
            InvokeEditCompleteEvent     = EventManager.RegisterRoutedEvent("InvokeEditComplete", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(PanelOrderEdit));
        public event            RoutedEventHandler
            InvokeEditComplete
        {
            add     { this.AddHandler(InvokeEditCompleteEvent, value); }
            remove  { this.RemoveHandler(InvokeEditCompleteEvent, value); }
        }

        public static readonly RoutedEvent
            InvokeEditClientEvent       = EventManager.RegisterRoutedEvent("InvokeEditClient", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(PanelOrderEdit));
        public event RoutedEventHandler
            InvokeEditClient
        {
            add     { this.AddHandler(InvokeEditClientEvent, value); }
            remove  { this.RemoveHandler(InvokeEditClientEvent, value); }
        }

        int                 updateID;
        int                 deadlineID;

        TableClient         clients;
        TableClientAffected affected;

        TableDeadline       deadline;
        TablePurchaseOrder  purchaseOrder;

        public List<int>    AffectedClients;

		public              PanelOrderEdit              ()
		{
			this.InitializeComponent();
		}

        private     void    LayoutRoot_IsVisibleChanged (object sender, DependencyPropertyChangedEventArgs e)
        {
            if (this.Visibility == Visibility.Visible)
            {
                if (this.CreateMode)
                {
                    this.ButtonEdit.Content = "Create";
                }
                else
                {
                    this.ButtonEdit.Content = "Update";
                }

                FocusHelper.Focus(this.TextDescription);
            }
        }

        private     void    ButtonRemove_Click          (object sender, RoutedEventArgs e)
        {
            this.ClearData();

            this.RaiseEvent(new RoutedEventArgs(InvokeEditCompleteEvent));
        }
        private     void    ButtonEdit_Click            (object sender, RoutedEventArgs e)
        {
            int poPK;
            int dlPK;

            bool    isError         = false;
            string  errorDetails    = string.Empty;

            int     serial;
            float   amount;

            if (!int.TryParse(this.TextSerial.Text, out serial))
            {
                isError = true;

                errorDetails += "Incorrect serial ID\n";
            }

            if (!float.TryParse(this.TextAmount.Text, out amount))
            {
                isError = true;

                errorDetails += "Incorrect amount format\n";
            }

            if (this.AffectedClients == null)
            {
                isError = true;

                errorDetails += "Affected clients missing\n";
            }

            if (isError)
            {
                EagleMessageBox.ShowMessageBox("Input error", "There are value(s) in an incorrect format!\n\n" + errorDetails, MessageBoxImage.Warning, MessageBoxButton.OK);

                return;
            }

            if (this.CreateMode)
            {
                poPK = ScanAvailablePOID();
                dlPK = ScanAvailablePODeadline();

                deadline.Create(dlPK, new List<object>() { dlPK, this.DateDeadline.SelectedDate.Value.ToBinary(), true });

                purchaseOrder.Create(poPK, new List<object>()
                {
                    poPK,
                    dlPK,
                    serial,
                    amount,
                    this.TextCompany.Text,
                    this.TextDescription.Text,
                    true
                });
            }
            else
            {
                poPK = updateID;
                dlPK = deadlineID;

                deadline.Update(dlPK, new List<object>() { dlPK, this.DateDeadline.SelectedDate.Value.ToBinary(), true });

                purchaseOrder.Update(poPK, new List<object>()
                {
                    poPK,
                    dlPK,
                    serial,
                    amount,
                    this.TextCompany.Text,
                    this.TextDescription.Text,
                    true
                });
            }

            this.affected.Remove(poPK);
            foreach (int id in this.AffectedClients)
            {
                this.affected.Create(poPK, new List<object>() { poPK, id });
            }

            this.RaiseEvent(new RoutedEventArgs(InvokeEditCompleteEvent));
        }
        private     void    ButtonClients_Click         (object sender, RoutedEventArgs e)
        {
            this.RaiseEvent(new RoutedEventArgs(InvokeEditClientEvent));
        }

        public      void    LinkPOTable                 (TablePurchaseOrder po, TableDeadline deadline, TableClient client, TableClientAffected affected)
        {
            this.purchaseOrder  = po;
            this.deadline       = deadline;

            this.clients        = client;
            this.affected       = affected;
        }

        public      void    ClearData                   ()
        {
            this.TextAmount.Text        = string.Empty;
            this.TextCompany.Text       = string.Empty;
            this.TextDescription.Text   = string.Empty;
            this.TextSerial.Text        = string.Empty;

            this.DateDeadline.DisplayDate   = DateTime.Today;

            if (this.AffectedClients != null)
                this.AffectedClients.Clear();
        }
        public      void    PassData                    (int PK, int dPK, POPanelEdit info)
        {
            this.updateID   = PK;
            this.deadlineID = dPK;

            this.TextAmount.Text            = info.Amount;
            this.TextCompany.Text           = info.Company;
            this.TextDescription.Text       = info.Description;
            this.TextSerial.Text            = info.ID;

            this.DateDeadline.SelectedDate = DateTime.FromBinary(info.Deadline);

            // propagate affected clients here
            this.AffectedClients = new List<int>();

            this.affected.Filter("POID = " + PK);
            foreach (List<object> row in this.affected.TableData)
            {
                this.AffectedClients.Add((int)row[1]);
            }
        }

        private     int     ScanAvailablePOID           ()
        {
            int returnIndex = 1;
            for (int i = 0; i < this.purchaseOrder.TableData.Count; i++)
            {
                returnIndex++;

                if (i < (this.purchaseOrder.TableData.Count - 2))
                {
                    if (((int)this.purchaseOrder.TableData[i][0] + 1) != ((int)this.purchaseOrder.TableData[i + 1][0]))
                    {
                        return returnIndex;
                    }
                }
            }

            return returnIndex;
        }
        private     int     ScanAvailablePODeadline     ()
        {
            int returnIndex = 1;
            for (int i = 0; i < this.deadline.TableData.Count; i++)
            {
                returnIndex++;

                if (i < (this.deadline.TableData.Count - 2))
                {
                    if (((int)this.deadline.TableData[i][0] + 1) != ((int)this.deadline.TableData[i + 1][0]))
                    {
                        return returnIndex;
                    }
                }
            }

            return returnIndex;
        }

        private     void    TextDescription_TextChanged (object sender, TextChangedEventArgs e)
        {

        }

        private     void    TextSerial_TextChanged      (object sender, TextChangedEventArgs e)
        {
            if (this.TextDescription.Text.Length > 0)
                this.ButtonEdit.IsEnabled = true;
            else
                this.ButtonEdit.IsEnabled = false;
        }
	}
}
